<?php
class Zpdo{
	protected static $dbconf;
	protected static $dbconn;
	
	protected $_table;
	protected $_field;
	protected $_where;
	protected $_group;
	protected $_order;
	protected $_limit;
	protected $_join;
	protected $_page;
	protected $_pagesize;
	protected $_pageinfo = array();
	protected $_sql;
	
	function __construct($tablename=''){
		if (!empty($tablename)) $this->table($tablename);
		if(!self::$dbconf)
			self::$dbconf = ZKF::C('db');
		if(!self::$dbconn){
	        try {
	            $h_param = array(
	                PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
	            );
	            if (@self::$dbconf['DB_CHARSET'] != '') {
	                $h_param[PDO::MYSQL_ATTR_INIT_COMMAND] = 'SET NAMES ' . @self::$dbconf['DB_CHARSET'];
	            }
	            if (@self::$dbconf['DB_PCONNECT']) {
	                $h_param[PDO::ATTR_PERSISTENT] = true;
	            }
	            $dsn = "mysql:host=" . @self::$dbconf['DB_HOST'] . ";port=" . @self::$dbconf['DB_PORT'] . ";dbname=" . @self::$dbconf['DB_NAME'];
	            self::$dbconn = new PDO($dsn, @self::$dbconf['DB_USER'], @self::$dbconf['DB_PWD'], $h_param);
	        } catch (PDOException $e) {
	            throw new ErrorException('Unable to connect to db server. Error:' . $e->getMessage(), 31);
	        }
		}
    }

    public function fetch($fetchmode='hash') {
		if (!isset($this->_page) || $this->_page <= 0)
			$this->_page = 1;
        $_star = ($this->_page - 1) * $this->_pagesize;
        $_limit_temp = (isset($this->_pagesize) && $this->_pagesize > 0) ? "limit {$_star},{$this->_pagesize}" : $this->_limit;
		$this->_sql = "select {$this->_field} from {$this->_table} {$this->_join} {$this->_where} {$this->_group} {$this->_order} {$_limit_temp}";
		$sth = self::$dbconn->prepare($this->_sql);
        $sth->execute();
		switch ($fetchmode) {
            case 'num':
                $result = $sth->fetchAll(PDO::FETCH_NUM);
                break;
            case 'hash':
                $result = $sth->fetchAll(PDO::FETCH_ASSOC);
                break;
            case 'one':
                $result = $sth->fetch();
                break;
            case 'all':
            default:
                $result = $sth->fetchAll();
        }
        $this->_pageinfo['page'] = $this->_page;
        $this->_pageinfo['size'] = $this->_pagesize;
        $this->_pageinfo['total'] = $this->count(0);
        $this->default_param();
        return $result;
	}

	final public function fetchAll() {
		return $this->fetch('all');
	}
	
	final public function fetchOne() {
		return $this->fetch('one');
	}	
	
	final public function fetchNum() {
		return $this->fetch('num');
	}	
	
	final public function fetchHash() {
		return $this->fetch('hash');
	}
	
	public function add($param) {
		$a_add_placeholder = $a_add_field = $a_add_value = array();
        foreach ($param as $a_add_field[] => $a_add_value[]) {
            array_push($a_add_placeholder, '?');
        }
        $add_part = '`' . implode('`,`', $a_add_field) . '`';
        $placeholder_part = implode(',', $a_add_placeholder);
        $this->_sql = "insert into {$this->_table} ({$add_part}) values ({$placeholder_part})";
        $sth = self::$dbconn->prepare($this->_sql);
        $sth->execute($a_add_value);
        $this->default_param();
        return self::$dbconn->lastInsertId();
	}
	
	public function del($condition = '') {
    	if(!empty($condition)) $this->where($condition);
    	$this->_sql = "delete from {$this->_table} {$this->_where}";
		$sth = self::$dbconn->query($this->_sql) or die(self::$dbconn->errorInfo());
        $this->default_param();
        return $sth->rowCount();
	}
	
	public function save($param, $condition = '') {
    	if(!empty($condition)) $this->where($condition);
		$a_update_field = $a_update_value = array();
		
        foreach ($param as $colname => $a_update_value[]) {
            array_push($a_update_field, "`$colname`=?");
        }
        $update = implode(',', $a_update_field);
        $this->_sql = "update {$this->_table} set {$update} {$this->_where}";
        $sth = self::$dbconn->prepare($this->_sql);
        $sth->execute($a_update_value);
        $this->default_param();
        return $sth->rowCount();
	}	
	
	public function count($statu=1) {
    	$_sql = "select count(1) from {$this->_table} {$this->_join} {$this->_where}";
    	if($statu==1) $this->_sql=$_sql;
		$sth = self::$dbconn->prepare($_sql);
        $sth->execute();
        $this->default_param();
        return $sth->fetchColumn();
	}
	
	public function pageinfo() {
        return $this->_pageinfo;
	}
	
	public function handle($sqlstr = '') {
		$this->_sql = $sqlstr;
        $types = explode(' ', $this->_sql);
        $type = strtolower($types[0]);
        switch ($type) {
            case 'select':
                $sth = self::$dbconn->prepare($this->_sql);
                $sth->execute();
                $result = $sth->fetchAll(PDO::FETCH_ASSOC);
                return $result;
                break;

            case 'insert':
                self::$dbconn->query($this->_sql) or die(self::$dbconn->errorInfo());
                return self::$dbconn->lastInsertId();
                break;

            case 'update':
                $sth = self::$dbconn->query($this->_sql) or die(self::$dbconn->errorInfo());
                return $sth->rowCount();
                break;

            case 'delete':
                self::$dbconn->query($this->_sql) or die(self::$dbconn->errorInfo());
                return true;
                break;

            case 'replace':
                self::$dbconn->query($this->_sql) or die(self::$dbconn->errorInfo());
                return self::$dbconn->lastInsertId();
                break;

            default:
                self::$dbconn->query($this->_sql) or die(self::$dbconn->errorInfo());
        }
    }
	
    public function table($tablename='') {
    	$this->_table = $tablename;
    	return $this;
    }
    
	public function field($field='*') {
    	$this->_field = $field;
    	return $this;
    }
    
	public function where($where='') {
    	$this->_where = empty($where)?'':'where '.$where;
    	return $this;
    }

	public function group($group='') {
    	$this->_group = empty($group)?'':'group by '.$group;
    	return $this;
    }

	public function order($order='') {
    	$this->_order = empty($order)?'':'order by '.$order;
    	return $this;
    }

	public function limit($limit='') {
    	$this->_limit = empty($limit)?'':'limit '.$limit;
    	return $this;
    }
    
	public function join($join='') {
    	$this->_join = $join;
    	return $this;
    }
    
    public function page($page=1,$pagesize=10) {
    	$this->_page = intval($page);
    	$this->_pagesize = intval($pagesize);
    	return $this;
    }
    
    protected function default_param() {
    	$this->_field = $this->_group = $this->_join = $this->_limit = $this->_order = $this->_table = $this->_where = null;
    	$this->_page = 1;
    	$this->_pagesize = 10;
    }
	
    public function sql(){
    	return $this->_sql.'<br>';
    }
}
?>